package com.vdg.lockphotos.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Toast;

public class Utilities {
	public static final String EMO_FOLDER_NAME = "emo";
	public static final String BACKGROUND_FOLDER_NAME = "background";
	public static final String DATA_FOLDER_NAME = "s2talk";
	private final static String PRE_NAME = "cfgprefrence";
	public static final String CHAT_HOST_NAME = "@xmpp.s2talk.vn";
	public static final String ROOM_HOST_NAME = "@conference.xmpp.s2talk.vn";
	public static final String DELIMITER = ":";
	public static final String EMO_ANIMATION_TAG = "gif_emo";
	public static final String IMAGE_SIZE_TAG = "image_size";
	public static final String IMAGE_URL_TAG = "image_url";
	public static final String AUDIO_URL_TAG = "audio_url_tag";
	public static final String AUDIO_DURATION = "audio_duration";
	public static final String IMAGE_THUMBNAIL_URL_TAG = "image_thumbnail_url";
	public static final String BACKGROUND_URL_TAG = "bg_url";
	public static final String MESSAGE_TYPE = "message_type";
	public static final String BACKGROUND_NAME = "bg_name";
	public static final String LOCATION_TAG = "location_tag";
	private static final String PASS_CODE_SAVE_KEY = "pass_code_key";
	private static final String TAG = "Utilities";
	private static final int SECOND_MILLIS = 1000;
	private static final int MINUTE_MILLIS = 60 * SECOND_MILLIS;
	private static final int HOUR_MILLIS = 60 * MINUTE_MILLIS;
	private static final int DAY_MILLIS = 24 * HOUR_MILLIS;
	private static final Charset UTF_8 = Charset.forName("UTF-8");

	static final String decode(String in) {
		in = "c\u00f3 ai";
		String str = in.split(" ")[0];
		str = str.replace("\\", "");
		String[] arr = str.split("u");
		String text = "";
		for (int i = 1; i < arr.length; i++) {
			int hexVal = Integer.parseInt(arr[i], 16);
			text += (char) hexVal;
		}
		return text;
	}

	public static void showToast(String message, Context context) {
		Toast.makeText(context, message, Toast.LENGTH_LONG).show();
	}

	public static void showLongToast(String message, Context context) {
		final Toast toast = Toast
				.makeText(context, message, Toast.LENGTH_SHORT);
		toast.show();
		Handler handler = new Handler();
		handler.postDelayed(new Runnable() {
			@Override
			public void run() {
				toast.cancel();
			}
		}, 5000);
	}

	public static String forceUtf8Coding(String input) {
		// String result = decode(input);
		// Log.v(TAG, "status result = " + result);
		return input;
	}

	public static void unbindDrawables(View view) {
		if (view.getBackground() != null) {
			view.getBackground().setCallback(null);
		}
		if (view instanceof ViewGroup) {
			for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
				unbindDrawables(((ViewGroup) view).getChildAt(i));
			}
			((ViewGroup) view).removeAllViews();
		}
	}

	public static boolean compareTwoArrayList(ArrayList<String> list1,
			ArrayList<String> list2) {
		if (list1.size() != list2.size()) {
			return false;
		} else {
			Collections.sort(list1);
			Collections.sort(list2);
			for (int i = 0; i < list1.size(); i++) {
				if (!list1.get(i).equals(list2.get(i))) {
					return false;
				}
			}
		}
		return true;
	}

	public static byte[] getbyte(String path) throws IOException {
		int bytesRead;
		FileInputStream is = new FileInputStream(path);
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		byte[] b = new byte[1024];
		while ((bytesRead = is.read(b)) != -1) {
			bos.write(b, 0, bytesRead);
		}
		byte[] bytes = bos.toByteArray();
		return bytes;
	}

	public static String getSizeOfThumbnail(Context context) {
		return "_t";
	}

	public static final String formatMessage(HashMap<String, String> param) {
		String body = "";
		for (Entry<String, String> entry : param.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			if (body.equals("")) {
				body = key + DELIMITER + value;
			} else {
				body = body + ";" + key + DELIMITER + value;

			}
		}
		return "< " + body + "/>";
	}

	public static final String getMessageFromFormat(String formatMessage,
			String tag) {
		int start = formatMessage.indexOf(tag + DELIMITER)
				+ (tag + DELIMITER).length();
		int end;
		if (formatMessage.indexOf(";", start) == -1) {
			end = formatMessage.indexOf("/>", start);
		} else {
			end = formatMessage.indexOf(";", start);
		}
		Log.v(TAG, "body " + formatMessage + "start = " + start + "end =" + end);
		if (start == -1 || end == -1 || start > end) {
			return null;
		}
		return formatMessage.substring(start, end);
	}

	public static String getDateTimeForMsgScreen(Long time) {
		Calendar timeServer = Calendar.getInstance();
		timeServer.setTimeInMillis(time);

		Calendar timeDevice = Calendar.getInstance();
		timeDevice.setTimeInMillis(System.currentTimeMillis());

		if (timeServer.get(Calendar.YEAR) == timeDevice.get(Calendar.YEAR)
				&& timeServer.get(Calendar.MONTH) == timeDevice
						.get(Calendar.MONTH)
				&& timeServer.get(Calendar.DAY_OF_MONTH) == timeDevice
						.get(Calendar.DAY_OF_MONTH)) {
			return new SimpleDateFormat("HH:mm").format(new Date(time));
		} else {
			return new SimpleDateFormat("yyyy/MM/dd HH:mm").format(new Date(
					time));
		}
	}

	public static String getDateTimeCallLog(Long time) {
		Calendar timeServer = Calendar.getInstance();
		timeServer.setTimeInMillis(time);

		Calendar timeDevice = Calendar.getInstance();
		timeDevice.setTimeInMillis(System.currentTimeMillis());

		if (timeServer.get(Calendar.YEAR) == timeDevice.get(Calendar.YEAR)
				&& timeServer.get(Calendar.MONTH) == timeDevice
						.get(Calendar.MONTH)
				&& timeServer.get(Calendar.DAY_OF_MONTH) == timeDevice
						.get(Calendar.DAY_OF_MONTH)) {
			return new SimpleDateFormat("HH:mm").format(new Date(time));
		} else {
			return new SimpleDateFormat("HH:mm dd/MM/yyyy").format(new Date(
					time));
		}
	}

	public static boolean saveStringToSharedPreferences(String save,
			Context context, String key) {
		SharedPreferences mPrefrence = context
				.getSharedPreferences(PRE_NAME, 0);
		Editor mPrefrenceEdit = mPrefrence.edit();
		if (mPrefrenceEdit == null) {
			return false;
		}
		mPrefrenceEdit.putString(key, save);
		return mPrefrenceEdit.commit();
	}

	public static String getStringFromSharedPreferences(String key,
			Context context) {
		SharedPreferences mPrefrence = context
				.getSharedPreferences(PRE_NAME, 0);
		if (mPrefrence == null) {
			return "";
		}
		return mPrefrence.getString(key, "");
	}

	public static int getIntFromMap(Map<String, Object> map, String key) {
		int res = 0;
		if (map == null || map.get(key) == null)
			return res;
		if (map.get(key) instanceof String)
			res = Integer.parseInt((String) map.get(key));
		else
			res = (Integer) map.get(key);
		return res;
	}

	public static String genChatroomID() {
		UUID uid = UUID.randomUUID();
		return uid + "@conference.xmpp.s2talk.vn";
	}

	public static String getTimeDisplayForAudioTime(Long time) {
		return new SimpleDateFormat("mm:ss").format(new Date(time));
	}

	public static String getRoomIDFromJID(String jid) {
		String roomID = jid;
		if (roomID.contains("/")) {
			roomID = jid.split("/")[0];
			return roomID;
		}
		Log.v(TAG, " jid =" + jid);
		return null;
	}

	public static String getNickNameFromAdress(String adress) {
		if (adress.contains("/") && !adress.contains(Utilities.ROOM_HOST_NAME)) {
			return adress.split("/")[0].toLowerCase().replace(
					Utilities.CHAT_HOST_NAME, "");
		}
		if (adress.contains(Utilities.ROOM_HOST_NAME)) {
			return adress.split("/")[1];
		}
		return adress.toLowerCase().replace(Utilities.CHAT_HOST_NAME, "");
	}

	public static String getS2IDFromXmppAdress(String adress) {
		if (adress.contains("/") && !adress.contains(Utilities.ROOM_HOST_NAME)) {
			return adress.split("/")[0].toLowerCase().replace(
					Utilities.CHAT_HOST_NAME, "");
		}
		if (adress.contains(Utilities.ROOM_HOST_NAME)) {
			return adress.split("/")[1];
		}
		return adress.toLowerCase().replace(Utilities.CHAT_HOST_NAME, "");
	}

	public static String getAdress(String username) {
		if (!username.contains(Utilities.CHAT_HOST_NAME)) {
			return username + CHAT_HOST_NAME;
		}
		return username;
	}

	public static float getHeight(Activity activity, float rate) {
		WindowManager wm = (WindowManager) activity
				.getSystemService(Context.WINDOW_SERVICE);
		Display display = wm.getDefaultDisplay();
		return (getDisplaySize(display).x / 3.5f) * rate;
	}

	public static float getWidth(Activity activity) {
		WindowManager wm = (WindowManager) activity
				.getSystemService(Context.WINDOW_SERVICE);
		Display display = wm.getDefaultDisplay();
		android.util.Log.v(TAG, "width =" + getDisplaySize(display).x);
		return getDisplaySize(display).x / 3.5f;
	}

	@SuppressWarnings("deprecation")
	public static Point getDisplaySize(final Display display) {
		Point point = new Point();
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { // API
			display.getSize(point);
		} else {
			point.set(display.getWidth(), display.getHeight());
		}
		return point;
	}

	public static Drawable getDrawableFromName(String source, Context context) {
		Drawable drawFromPath;
		int path = context.getResources().getIdentifier(source, "drawable",
				"newtech.S2Talk");
		drawFromPath = (Drawable) context.getResources().getDrawable(path);
		drawFromPath.setBounds(0, 0, drawFromPath.getIntrinsicWidth(),
				drawFromPath.getIntrinsicHeight());
		return drawFromPath;
	}

	public static Bitmap resizeAndRotateBitmap(Bitmap m, Activity activity) {
		WindowManager wm = (WindowManager) activity
				.getSystemService(Context.WINDOW_SERVICE);
		Display display = wm.getDefaultDisplay();
		Point size = new Point();
		display.getSize(size);
		int targetWidth = size.x / 4;
		if (m.getWidth() > m.getHeight()) {
			// int targetWidth = activity.getResources().getDimensionPixelSize(
			// R.dimen.chat_image_size);
			float scale = (float) targetWidth / (float) m.getWidth();
			Matrix mt = new Matrix();
			mt.postScale(scale, scale);
			mt.postRotate(90);
			Log.v("debug",
					"width = " + m.getWidth() + "mheigh =" + m.getHeight());
			return Bitmap.createBitmap(m, 0, 0, m.getWidth(), m.getHeight(),
					mt, true);
		} else {
			// int height = activity.getResources().getDimensionPixelSize(
			// R.dimen.chat_image_size);
			float scale = (float) targetWidth / (float) m.getHeight();
			Matrix mt = new Matrix();
			mt.postRotate(90);
			mt.postScale(scale, scale);
			return Bitmap.createBitmap(m, 0, 0, m.getWidth(), m.getHeight(),
					mt, true);
		}
	}

	public static void scanMedia(Context context) {
		context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri
				.parse("file://" + Environment.getExternalStorageDirectory())));
	}

	public static Bitmap decodeFile(File f, Activity activity) {
		try {
			Display display = activity.getWindowManager().getDefaultDisplay();
			int width = display.getWidth();
			// Decode image size
			BitmapFactory.Options o = new BitmapFactory.Options();
			o.inJustDecodeBounds = true;
			BitmapFactory.decodeStream(new FileInputStream(f), null, o);

			// The new size we want to scale to
			final int REQUIRED_SIZE = (int) (width / 3);

			// Find the correct scale value. It should be the power of 2.
			int scale = 1;
			while (o.outWidth / scale / 2 >= REQUIRED_SIZE
					&& o.outHeight / scale / 2 >= REQUIRED_SIZE)
				scale *= 2;

			// Decode with inSampleSize
			BitmapFactory.Options o2 = new BitmapFactory.Options();
			o2.inSampleSize = scale;
			return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
		} catch (FileNotFoundException e) {
		}
		return null;
	}

	public static String recognize(String s) {
		s = s.replace("\n", "");
		s = s.replace("<p>", "").replace("</p>", "");
		s = s.replace("<p dir=ltr>", "");
		s = s.replace("<p dir=\"ltr\">", "");
		return s;
	}

	public static String getDate(long milliSeconds, String dateFormat) {
		// Create a DateFormatter object for displaying date in specified
		// format.
		DateFormat formatter = new SimpleDateFormat(dateFormat);

		// Create a calendar object that will convert the date and time value in
		// milliseconds to date.
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(milliSeconds);
		return formatter.format(calendar.getTime());
	}

	private static long getCurrentTime(Context context) {
		// TODO Auto-generated method stub
		return System.currentTimeMillis();
	}

	public static float dpToPx(Context context, int dp) {
		Resources r = context.getResources();
		float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
				r.getDisplayMetrics());
		return px;
	}

	private static void addImageGallery(File file, Context context) {
		ContentValues values = new ContentValues();
		values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
		context.getContentResolver().insert(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
	}

	public static void deleteFileFromMediaStore(
			final ContentResolver contentResolver, final File file) {
		String canonicalPath;
		try {
			canonicalPath = file.getCanonicalPath();
		} catch (IOException e) {
			canonicalPath = file.getAbsolutePath();
		}
		final Uri uri = MediaStore.Files.getContentUri("external");
		final int result = contentResolver.delete(uri,
				MediaStore.Files.FileColumns.DATA + "=?",
				new String[] { canonicalPath });
		if (result == 0) {
			final String absolutePath = file.getAbsolutePath();
			if (!absolutePath.equals(canonicalPath)) {
				contentResolver.delete(uri, MediaStore.Files.FileColumns.DATA
						+ "=?", new String[] { absolutePath });
			}
		}
	}

	public static String copy(File src, File dst, Context context,
			boolean isUpdateInMedia) throws IOException {
		InputStream in = new FileInputStream(src);
		OutputStream out = new FileOutputStream(dst);
		// Transfer bytes from in to out
		byte[] buf = new byte[1024];
		int len;
		while ((len = in.read(buf)) > 0) {
			out.write(buf, 0, len);
		}
		in.close();
		out.close();
		src.delete();
		if (isUpdateInMedia) {
			addImageGallery(dst, context);
		}
		Log.v("TAG", "delete file L:" + src.getAbsolutePath());
		return dst.getAbsolutePath();
	}

	public static String copy(File src, String name, Context context,
			boolean isUpdateInMedia) throws IOException, NameNotFoundException {
		InputStream in = new FileInputStream(src);
		File images = new File(getDataDir(context) + "/.images");
		if (!images.exists()) {
			images.mkdir();
		}
		File dst = new File(getDataDir(context) + "/.images/" + name);
		OutputStream out = new FileOutputStream(dst);
		// Transfer bytes from in to out
		byte[] buf = new byte[1024];
		int len;
		while ((len = in.read(buf)) > 0) {
			out.write(buf, 0, len);
		}
		in.close();
		out.close();
		if (isUpdateInMedia) {
			deleteFileFromMediaStore(context.getContentResolver(), src);
		}
		src.delete();
		return dst.getAbsolutePath();
	}

	public static String getDataDir(Context context)
			throws NameNotFoundException {
		return context.getPackageManager().getPackageInfo(
				context.getPackageName(), 0).applicationInfo.dataDir;
	}

	public static String getPassCode(Context context) {
		return Utilities.getStringFromSharedPreferences(PASS_CODE_SAVE_KEY,
				context);
	}

	public static void setPassCode(Context context, String passCode) {
		Utilities.saveStringToSharedPreferences(passCode, context,
				PASS_CODE_SAVE_KEY);
	}

	public static boolean isExternalStorageWritable() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)) {
			return true;
		}
		return false;
	}

	/* Checks if external storage is available to at least read */
	public static boolean isExternalStorageReadable() {
		String state = Environment.getExternalStorageState();
		if (Environment.MEDIA_MOUNTED.equals(state)
				|| Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
			return true;
		}
		return false;
	}
}
